package com.healthcloud.controller;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.exception.NetworkCode;
import com.google.gson.Gson;
import com.healthcloud.entity.*;
import com.healthcloud.rabbitmq.entity.Order;
import com.healthcloud.rabbitmq.service.OrderService;
import com.healthcloud.service.InstrumentInfoService;
import com.healthcloud.service.PatientService;
import com.healthcloud.service.SysUserService;
import com.healthcloud.service.TestResultService;
import com.healthcloud.utils.*;
import com.healthcloud.validator.ValidatorUtils;
import com.healthcloud.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author yucl
 * @date 2018/7/24
 */
@RestController
@RequestMapping("/smart")
@Slf4j
@Api(value = "poct仪器数据相关接口", description = "poct仪器数据相关接口")
public class SmartController {
    private static Logger logger = LoggerFactory.getLogger(SmartController.class);
    @Autowired
    private com.healthcloud.service.SmartService smartService;
    @Autowired
    private TestResultService testResultService;

//    @Autowired
//    private Producer producer;

    @Autowired
    private OrderService orderService;

    //分配给第三方平台的校验码
    public static final String SALT = "W2km0t2JbF6497v";

    public static final String TOKEN_掌护云 = "Mk345678912345678912345678912345";

    //掌护云key
    public static final String ACCESS_KEY = "b6c320b7564d4170b17f687882308dcb";

    //掌护云id
    public static final String ACCESS_ID = "437899101628438b86696e80ecf97659";

    private String[] bpArr = {"02052207100061", "02052207100086", "02052207100255", "02052207100144", "02052207100363", "02052207100353", "02052207100139", "02052207100106", "02052207100351", "02052207100152", "02052207100167", "02052207100367", "02052207100342", "02052207100123", "02052207100063", "02052104010266"};

    private String[] bsArr = {"2AM28R00491", "2AM28R00382", "2AM28R00270", "2AM28R00388", "2AM28R00417", "2ALCBR02318", "2ALCBR02224", "2ALCBR02543", "2AM28R00360", "2AM28R00513", "2ALCBR02160", "2AM28R00093", "2AM28R00229", "2AM28R00572", "2AM28R00371", "355B0001AD2"};

    @ApiOperation(value = "数据上传接口", notes = "数据上传接口")
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    @ResponseBody
    public R upload(PoctDataVO poctDataVO) throws Exception {


        log.info("数据上传接口，接受到的参数为:" + JSON.toJSON(poctDataVO));
        logger.info("数据上传接口，接受到的参数为:" + JSON.toJSON(poctDataVO));

        String itype = poctDataVO.getItype();
        if (Constants.TEST_DATA.equals(itype)) {
            //测试数据
            TestdataVO testdataVO = JSON.parseObject(poctDataVO.getTestdata(), TestdataVO.class);
            testdataVO.setMachineType(poctDataVO.getMachineType());
            return uploadTestData(testdataVO);
        }

        if (Constants.QUA_DATA.equals(itype)) {

            QuadataVO quadataVO = JSON.parseObject(poctDataVO.getQuadata(), QuadataVO.class);
            return uploadQuaData(quadataVO);
        }

        if (Constants.LOG_DATA.equals(itype)) {

            LogdataVO logdataVO = JSON.parseObject(poctDataVO.getLogdata(), LogdataVO.class);
            return uploadLogData(logdataVO);
        }


        if (Constants.VERSION_DATA.equals(itype)) {

            List<VersionModel> list = smartService.searchVersion(poctDataVO.getAppliance(), poctDataVO.getBVersion(), poctDataVO.getChildVersion());
            if (list != null && list.size() == 2) {
                String result = list.get(0).getAppAddress() + ","
                        + list.get(0).getChildVersion() + ","
                        + list.get(1).getAppAddress() + ","
                        + list.get(1).getChildVersion();

                Map<String, String> map = new LinkedHashMap<String, String>();
                map.put("hexLink", result.split(",")[0]);
                map.put("hexVersion", result.split(",")[1]);
                map.put("apkLink", result.split(",")[2]);
                map.put("apkVersion", result.split(",")[3]);
                return R.ok().put("data", map);


            } else {
                return R.error().put("code", "201").put("msg", "不存在");
            }
        }

        if (Constants.DB_DATA.equals(itype)) {
            String result = smartService.searchCheck(poctDataVO.getMachine(), poctDataVO.getCH(), poctDataVO.getProjectBatch(), poctDataVO.getProjectName());
            if (StringUtils.isBlank(result)) {
                return R.error().put("code", "201").put("msg", "不存在");
            } else {
                Map<String, String> map = new LinkedHashMap<String, String>();
                map.put("k", result.split(",")[0]);
                map.put("b", result.split(",")[1]);
                return R.ok().put("data", map);
            }
        }

        return R.error("itype 型号不匹配");
    }


    @ApiOperation(value = "测试数据上传参数说明", notes = "测试数据上传参数说明")
    @RequestMapping(value = "/upload/testdata", method = RequestMethod.GET)
    public R uploadTestData(TestdataVO testdataVO) throws Exception {
        log.info("测试数据上传参数说明，接受到的参数为:" + JSON.toJSON(testdataVO));
        logger.info("测试数据上传参数说明，接受到的参数为:" + JSON.toJSON(testdataVO));
        ValidatorUtils.validateEntity(testdataVO);

        String machineType = testdataVO.getMachineType();//仪器类型
        if ("SMART_IV_Plus".equals(machineType)) {
            testdataVO.setDataType(Constants.SMART_IV_Plus);
        }

        if ("FP-100".equals(machineType)) {
            testdataVO.setDataType(Constants.FP_100);
        }

        if ("acr".equals(machineType)) {
            testdataVO.setDataType(Constants.ACR);
        }

        if ("Hy-50".equals(machineType)) {
            testdataVO.setDataType(com.healthcloud.utils.Constants.Hy_50);
        }

        if ("MS-H630".equals(machineType)) {
            testdataVO.setDataType(Constants.MS_H630);
        }


        smartService.insertTestData(testdataVO);

        Order order = new Order();
        order.setId(new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + "&" + UUID.randomUUID().toString());
        order.setName("POCT数据上传");
        order.setMessageId(testdataVO.getMechineId() + "&" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + "&" + UUID.randomUUID().toString());
//        orderService.createOrder(order, FastJsonConvertUtil.convertObjectToJSON(testdataVO));
        //数据推送
//        producer.sendMessage(JSON.toJSON(testdataVO), Constants.SMART_DIRECT, Constants.SMART_POCT_ROUTINGKEY, order.getMessageId());
        return R.ok().put("msg", "接收成功");
    }


    @ApiOperation(value = "质控数据上传参数说明", notes = "质控数据上传参数说明")
    @RequestMapping(value = "/upload/quadata", method = RequestMethod.GET)
    public R uploadQuaData(QuadataVO quadataVO) throws Exception {

        ValidatorUtils.validateEntity(quadataVO);

        smartService.insertQuaData(quadataVO);

        return R.ok();

    }

    @ApiOperation(value = "日志数据上传参数说明", notes = "日志数据上传参数说明")
    @RequestMapping(value = "/upload/logdata", method = RequestMethod.GET)
    public R uploadLogData(LogdataVO logdataVO) throws Exception {

        ValidatorUtils.validateEntity(logdataVO);

        smartService.insertLogData(logdataVO);

        return R.ok().put("msg", "返回接收");
    }

    /**
     * 第三方数据查询
     *
     * @return
     */
    @ApiOperation(value = "第三方数据查询", notes = "第三方数据查询")
    @RequestMapping(value = "/testvalue", method = RequestMethod.GET)
    public R queryTestResult(TestDataQueryVO testDataQueryVO) throws Exception {


        int iIndex = 0;
        if (!testDataQueryVO.getPageindex().equals("0")) {
            iIndex = Integer.parseInt(testDataQueryVO.getPagesize()) * Integer.parseInt(testDataQueryVO.getPageindex());
        }


        String companykey = "rw2012";
        String mysign = EncryptUtil.encryption(testDataQueryVO.getCompanycode() +
                (testDataQueryVO.getBegintime() == null ? "" : testDataQueryVO.getBegintime()) +
                (testDataQueryVO.getEndtime() == null ? "" : testDataQueryVO.getEndtime()) + companykey);

        if (mysign.equals(testDataQueryVO.getSign())) {

            List<TestResultModel> testResults = smartService.getTestResults(testDataQueryVO.getIdcard(), testDataQueryVO.getBegintime(),
                    testDataQueryVO.getEndtime(), testDataQueryVO.getPagesize(),
                    String.valueOf(iIndex), testDataQueryVO.getTestitemname());

            return R.ok().put("testresult", testResults);
        } else {
            return R.error("sign签名错误");
        }

    }


    /**
     * 通过检测单id回查检测数据
     *
     * @return
     */
    @ApiOperation(value = "通过检测单id回查检测数据", notes = "通过检测单id回查检测数据")
    @RequestMapping(value = "/checkvalue", method = RequestMethod.GET)
    public R queryByTestListId(@ApiParam(name = "testListId", value = "检测单id") @RequestParam("testListId") String testListId,
                               @ApiParam(name = "sign", value = "密钥，向美康开发人员要") @RequestParam("sign") String sign) {

        if (StringUtils.isBlank(testListId) || StringUtils.isBlank(sign)) {
            throw new RRException("参数错误");
        }

        String companykey = "rw2012";
        String mysign = EncryptUtil.encryption(testListId + companykey);
        if (mysign.equals(sign)) {
            List<TestResultModel> testResult = smartService.checkTestResult(testListId);
            return R.ok().put("testresult", testResult);
        } else {
            return R.error("sign签名错误");
        }
    }


    /**
     * 根据sn号查询
     *
     * @param sn
     * @param sign
     * @return
     */
    @ApiIgnore
    @RequestMapping(value = "/SNcheck", method = RequestMethod.GET)
    public R queryBySN(@RequestParam("SN") String sn, @RequestParam("sign") String sign) throws Exception {

        if (StringUtils.isBlank(sn) || StringUtils.isBlank(sign)) {
            throw new RRException("参数错误");
        }

        SNCheckModel model = new SNCheckModel();
        model.setSN(sn);

        if (EncryptUtil.auth(sn + "rw2012", sign)) {
            List<SNCheckModel> list = smartService.checkSN(model);
            if (list.isEmpty()) {
                return R.ok().put("result", 0);
            }
            return R.ok().put("result", 1);
        } else {
            return R.error("sign签名错误");
        }

    }


    /**
     * 慢病管理获取病人列表
     *
     * @param hospId
     * @param time
     * @param sign
     * @return
     */
    @ApiIgnore
    @RequestMapping(value = "/getUserList", method = RequestMethod.GET)
    public R getUserList(@RequestParam("hospId") String hospId,
                         @RequestParam("time") String time,
                         @RequestParam("sign") String sign) throws Exception {

        if (StringUtils.isBlank(hospId) || StringUtils.isBlank(time) || StringUtils.isBlank(sign)) {
            throw new RRException("参数错误");
        }

        if (EncryptUtil.auth(hospId + time + "rw2012", sign)) {
            List<UserModel> list = smartService.searchUserList(hospId);
            return R.ok().put("result", list);
        } else {
            return R.error("sign签名错误");
        }
    }


    /**
     * 慢病管理获得远程血糖数据
     *
     * @param testDataQueryVO
     * @return
     * @throws Exception
     */
    @ApiIgnore
    @RequestMapping(value = "/getBsList", method = RequestMethod.GET)
    public R getBsList(TestDataQueryVO testDataQueryVO) throws Exception {


        int iIndex = Integer.parseInt(testDataQueryVO.getPagesize()) * (Integer.parseInt(testDataQueryVO.getPageindex()));

        if (StringUtils.isBlank(testDataQueryVO.getIdcard()) ||
                StringUtils.isBlank(testDataQueryVO.getCompanycode()) ||
                StringUtils.isBlank(testDataQueryVO.getSign())) {
            throw new RRException("参数错误");
        }


        String companykey = "rw2012";
        String mysign = EncryptUtil.encryption(testDataQueryVO.getCompanycode() +
                (testDataQueryVO.getBegintime() == null ? "" : testDataQueryVO.getBegintime()) +
                (testDataQueryVO.getEndtime() == null ? "" : testDataQueryVO.getEndtime()) + companykey);

        if (mysign.equals(testDataQueryVO.getSign())) {
            List<BsModel> testResults = smartService.searchBsList(testDataQueryVO.getIdcard(), testDataQueryVO.getBegintime(),
                    testDataQueryVO.getEndtime(), testDataQueryVO.getPagesize(), testDataQueryVO.getPageindex());
            return R.ok().put("testresult", testResults);
        } else {
            return R.error("sign签名错误");
        }
    }


    /**
     * 慢病管理获得远程血压数据
     *
     * @param testDataQueryVO
     * @return
     * @throws Exception
     */
    @ApiIgnore
    @RequestMapping(value = "/getBpList", method = RequestMethod.GET)
    public R getBpList(TestDataQueryVO testDataQueryVO) throws Exception {


        int iIndex = Integer.parseInt(testDataQueryVO.getPagesize()) * (Integer.parseInt(testDataQueryVO.getPageindex()));

        if (StringUtils.isBlank(testDataQueryVO.getIdcard()) ||
                StringUtils.isBlank(testDataQueryVO.getCompanycode()) ||
                StringUtils.isBlank(testDataQueryVO.getSign())) {
            throw new RRException("参数错误");
        }


        String companykey = "rw2012";
        String mysign = EncryptUtil.encryption(testDataQueryVO.getCompanycode() +
                (testDataQueryVO.getBegintime() == null ? "" : testDataQueryVO.getBegintime()) +
                (testDataQueryVO.getEndtime() == null ? "" : testDataQueryVO.getEndtime()) + companykey);

        if (mysign.equals(testDataQueryVO.getSign())) {
            List<BpModel> testResults = smartService.searchBpList(testDataQueryVO.getIdcard(), testDataQueryVO.getBegintime(),
                    testDataQueryVO.getEndtime(), testDataQueryVO.getPagesize(), testDataQueryVO.getPageindex());
            return R.ok().put("testresult", testResults);
        } else {
            return R.error("sign签名错误");
        }
    }

    @Autowired
    private InstrumentInfoService instrumentInfoService;

    /**
     * 血糖测试结果上传
     *
     * @throws Exception
     */
    @ApiIgnore
    @RequestMapping(value = "/bsUpload", method = RequestMethod.POST)
    public R bsUpload(HttpServletRequest request) throws Exception {
        // todo
        String data = SmartUtil.getRequestPayload(request);
        BsDataVO bsDataVO = JSON.parseObject(data, BsDataVO.class);
        log.info("血糖测试结果上传，接受到的参数为:" + JSON.toJSON(bsDataVO));
        logger.info("血糖测试结果上传，接受到的参数为:" + JSON.toJSON(bsDataVO));
        Head head = bsDataVO.getHead().get(0);
        String signature = head.getSignature();
        String timestamp = head.getTimestamp();
        String randomnumber = head.getRandomnumber();
        String signature_key = "q6qyYVJz7hhqqFTc28c1MXqDaOIH1brOkQ2exjloqyYj3GNtm5";
//        String signature_key = "2aed492275e5befe9b0fd80db6ed66a4";
        if (EncryptUtil.auth(timestamp + signature_key + randomnumber, signature)) {

            try {
                Msgdata msgdata = bsDataVO.getMsgdata().get(0);


                Order order = new Order();
                order.setId(new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + "&" + UUID.randomUUID().toString());
                order.setName("血糖数据上传");
                order.setMessageId(msgdata.getDevicesn() + "&" +
                        new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + "&" + UUID.randomUUID().toString());
                orderService.createOrder(order, FastJsonConvertUtil.convertObjectToJSON(bsDataVO));
                //数据推动到队列
/*                producer.sendMessage(JSON.toJSON(bsDataVO.getMsgdata().get(0)),
                        Constants.SMART_DIRECT, Constants.SMART_BS_ROUTINGKEY, order.getMessageId());*/

                // todo
                // 根据imei查询身份证号
                String idCard = "";
                InstrumentInfoEntity instrumentInfoEntity = instrumentInfoService.getBySn(msgdata.getDevicesn());
                if (Objects.nonNull(instrumentInfoEntity) && org.apache.commons.lang3.StringUtils.isNotBlank(instrumentInfoEntity.getIdCard())) {
                    idCard = instrumentInfoEntity.getIdCard();
                    TestResult testresult = new TestResult();
                    testresult.setIdCard(idCard);
                    testresult.setTestValue(msgdata.getResult());
                    testresult.setTestTime(DateUtils.strToDate(msgdata.getTesttime(), "yyyy-MM-dd HH:mm:ss"));
                    testresult.setIdCard(idCard);
                    testresult.setMkMedicalInstrumentId(msgdata.getDevicesn());
                    testresult.setValueUnit("mmol/L");
                    if (testresult.getTestTime().getHours() > 0 && testresult.getTestTime().getHours() < 8) {
                        testresult.setTestItemCode("105001");
                    } else {
                        testresult.setTestItemCode("105002");
                    }
                    testResultService.saveBloodSugar(testresult);
                    SysUserEntity sysUserEntity = getOpenIdByIdCard(idCard);
                    if (Objects.nonNull(sysUserEntity)) {
                        String openId = sysUserEntity.getWxOpenId();
                        if (org.apache.commons.lang3.StringUtils.isNotBlank(openId)) {
                            try {
                                pushBsMpMsg(msgdata.getTesttime(), msgdata.getResult(), openId,testresult.getTestItemCode());
                            } catch (Exception e) {
                                log.error(e.getMessage(), e);
                            }
                        }

                    }

                }
                msgdata.setIdCard(idCard);
                smartService.bsUpload(msgdata);


                R r = new R();
                r.put("statusCode", "00");
                r.put("desc", "成功");
                return r;
            } catch (Exception e) {

                R r = new R();
                r.put("statusCode", "03");
                r.put("desc", "服务器异常");
                return r;

            }
        } else {
            R r = new R();
            r.put("statusCode", "02");
            r.put("desc", "数据错误");
            return r;
        }

    }

    @Resource
    private PatientService patientService;
    @Resource
    private SysUserService sysUserService;

    private SysUserEntity getOpenIdByIdCard(String idCard) {
        Patient patient = patientService.findByIdCard(idCard);
        if (Objects.nonNull(patient)) {
            SysUserEntity sysUser = sysUserService.queryObjectByid(patient.getUserId().longValue());
            if (Objects.nonNull(sysUser)) {
                return sysUser;
            }

        }
        return null;
    }

    private void pushBsMpMsg(String time, String value, String openId, String testItemCode) {
        WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl();
        config.setAppId("wx606be78e181b64e0"); // 设置微信公众号的appid
        config.setSecret("131557309670e7ed8c33bf0a24ca84c2"); // 设置微信公众号的app corpSecret


        WxMpService wxService = new WxMpServiceImpl();// 实际项目中请注意要保持单例，不要在每次请求时构造实例，具体可以参考demo项目
        wxService.setWxMpConfigStorage(config);
        double v = Double.parseDouble(value);
        if (testItemCode.equals("105001")) {
            if (v >= 7.10000d) {
                value = value + "  偏高";
            }

            if (v <= 4.40000d) {
                value = value + "  偏低";
            }
        }

        if (testItemCode.equals("105002")) {
            if (v >= 11.10000d) {
                value = value + "  偏高";
            }

            if (v <= 4.40000d) {
                value = value + "  偏低";
            }
        }

        // 发送模板消息接口
        WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                // 接收者openid
                .toUser(openId)
                // 模板id
                .templateId("t_uO4jOw2wj98UG78dxy68sX7ZeOIiQhOzmmkmDp6q4")
                // 模板跳转链接
                .build();
        // 添加模板数据
        templateMessage.addData(new WxMpTemplateData("time3", time))
                .addData(new WxMpTemplateData("thing6", value));
        String msgId = null;
        try {
            // 发送模板消息
            msgId = wxService.getTemplateMsgService().sendTemplateMsg(templateMessage);
        } catch (WxErrorException e) {
            e.printStackTrace();
        }
    }



    private void pushBpMpMsg(String time, String name, String highestBpSystolic /*收缩压*/, String highestBpDiastolic /*舒张压*/, String pulse /*脉搏*/, String openId) {
        WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl();
        config.setAppId("wx606be78e181b64e0"); // 设置微信公众号的appid
        config.setSecret("131557309670e7ed8c33bf0a24ca84c2"); // 设置微信公众号的app corpSecret


        WxMpService wxService = new WxMpServiceImpl();// 实际项目中请注意要保持单例，不要在每次请求时构造实例，具体可以参考demo项目
        wxService.setWxMpConfigStorage(config);

        // 发送模板消息接口
        WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                // 接收者openid
                .toUser(openId)
                // 模板id
                .templateId("JvxbDOWmLMr_7tGnmr0N660V9Sz0zvJN7e99wlXvMfU")
                // 模板跳转链接
                .build();
        // 添加模板数据
        double v = Double.parseDouble(highestBpSystolic);
        List<String> msg = new ArrayList<>();
        msg.add(" ");
        if (v >= 140) {
//            highestBpSystolic = highestBpSystolic + "  偏高";
            highestBpSystolic = highestBpSystolic  ;
            msg.add("收缩压 偏高");

        }
        if (v <= 90) {
//            highestBpSystolic = highestBpSystolic + "  偏低";
            highestBpSystolic = highestBpSystolic ;
            msg.add("收缩压 偏低");
        }
        double v1 = Double.parseDouble(highestBpDiastolic);
        if (v1 >= 90) {
//            highestBpDiastolic = highestBpDiastolic + "  偏高";
            highestBpDiastolic = highestBpDiastolic ;
            msg.add("舒张压 偏高");
        }
        if (v1 <= 60) {
//            highestBpDiastolic = highestBpDiastolic + "  偏低";
            highestBpDiastolic = highestBpDiastolic ;
            msg.add("舒张压 偏低");
        }
        templateMessage.addData(new WxMpTemplateData("time2", time))
                .addData(new WxMpTemplateData("thing4", name))
                .addData(new WxMpTemplateData("character_string5", highestBpSystolic + "/" +highestBpDiastolic))
                .addData(new WxMpTemplateData("number6", pulse))
                .addData(new WxMpTemplateData("thing8", msg.stream().collect(Collectors.joining(","))))
        ;
        String msgId = null;
        try {
            // 发送模板消息
            msgId = wxService.getTemplateMsgService().sendTemplateMsg(templateMessage);
        } catch (WxErrorException e) {
            e.printStackTrace();
        }
    }


    /**
     * 血压测试结果上传
     *
     * @param bpUploadModel
     * @return
     */
//    @ApiIgnore
    @RequestMapping(value = "/bpUpload", method = RequestMethod.GET)
    public R bpUpload(BpUploadModel bpUploadModel) throws Exception {
        // todo
//        ValidatorUtils.validateEntity(bpUploadModel);
        log.info("血糖测试结果上传，接受到的参数为:" + JSON.toJSON(bpUploadModel));
        logger.info("血糖测试结果上传，接受到的参数为:" + JSON.toJSON(bpUploadModel));
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
        TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
        TimeZone.setDefault(tz);

        if ("0".equals(bpUploadModel.getSys()) && "0".equals(bpUploadModel.getDia()) && "0".equals(bpUploadModel.getPul())) {
        } else {

            //过滤相同的数据
            List<BpUploadModel> mode = smartService.selectOne(bpUploadModel);
            if ("865024034148449".equals(bpUploadModel.getImei())) {
                mode = null;
            }

            if (mode == null || mode.isEmpty()) {

                //数据推送

                Order order = new Order();
                order.setId(new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + "&" + UUID.randomUUID().toString());
                order.setName("血压数据上传");
                order.setMessageId(bpUploadModel.getImei() + "&" +
                        new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + "&" + UUID.randomUUID().toString());
                orderService.createOrder(order, FastJsonConvertUtil.convertObjectToJSON(bpUploadModel));
//                producer.sendMessage(JSON.toJSON(bpUploadModel), Constants.SMART_DIRECT, Constants.SMART_BP_ROUTINGKEY, order.getMessageId());


                // todo
                // 根据imei查询身份证号
                String idCard = "";
                InstrumentInfoEntity instrumentInfoEntity = instrumentInfoService.getBySn(bpUploadModel.getImei());
                if (Objects.nonNull(instrumentInfoEntity) && org.apache.commons.lang3.StringUtils.isNotBlank(instrumentInfoEntity.getIdCard())) {
                    idCard = instrumentInfoEntity.getIdCard();
                    // 舒张压
                    Double szyValue = Double.parseDouble(bpUploadModel.getDia());
                    // 收缩压
                    Double ssyValue = Double.parseDouble(bpUploadModel.getSys());
                    // 周期脉搏
                    Double heartRate = Double.parseDouble(bpUploadModel.getPul());
                    Date testTime = DateUtils.strToDate(bpUploadModel.getTime(), DateUtils.YYYY_MM_DD_HH_MM_SS);

                    testResultService.saveBloodPressure(bpUploadModel.getImei(), idCard, szyValue, ssyValue, heartRate, testTime);

                    SysUserEntity sysUserEntity = getOpenIdByIdCard(idCard);
                    if (Objects.nonNull(sysUserEntity)) {
                        String openId = sysUserEntity.getWxOpenId();
                        try {
                            pushBpMpMsg(bpUploadModel.getTime(), sysUserEntity.getRealName(), bpUploadModel.getSys(), bpUploadModel.getDia(), bpUploadModel.getPul(), openId);
                        } catch (Exception e) {
                            log.error(e.getMessage(), e);
                        }
                    }
                }
                bpUploadModel.setIdCard(idCard);
                smartService.bpUpload(bpUploadModel);

            }
        }

        R r = new R();
        r.put("statusCode", 200);
        r.put("message", "上传数据成功");
        r.put("serveTime", format.format(new Date()));
        return r;
    }


    /**
     * 脉搏波 - 血压测试结果上传 GET方式
     *
     * @param jsonData
     * @return
     */
    @RequestMapping(value = "/bpUpload/bpg", method = RequestMethod.GET)
    public R bpUploadbpg2Get(@RequestParam(value = "threeJsonData", required = false) final String jsonData) throws Exception {

        BpUploadModel2BPG bpUploadModel2BPG = new Gson().fromJson(jsonData, BpUploadModel2BPG.class);
        log.info(" 脉搏波 - 血压测试结果上传，接受到的参数为:" + JSON.toJSON(bpUploadModel2BPG));
        logger.info(" 脉搏波 - 血压测试结果上传，接受到的参数为:" + JSON.toJSON(bpUploadModel2BPG));
        log.info("GET接收到血压机上传数据：{}", bpUploadModel2BPG);

        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
        TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
        TimeZone.setDefault(tz);

        BpUploadModel bpUploadModel = new BpUploadModel();
        bpUploadModel.setDia(bpUploadModel2BPG.getLowVoltage());
        bpUploadModel.setImei(bpUploadModel2BPG.getDeviceSim());
        bpUploadModel.setPul(bpUploadModel2BPG.getPulse());
        bpUploadModel.setSys(bpUploadModel2BPG.getHighPressure());
        bpUploadModel.setAno("0");
        bpUploadModel.setTime(bpUploadModel2BPG.getUploadTime());
        bpUploadModel.setUser("3");


        String idCard = "";
        InstrumentInfoEntity instrumentInfoEntity = instrumentInfoService.getBySn(bpUploadModel.getImei());
        if (Objects.nonNull(instrumentInfoEntity) && org.apache.commons.lang3.StringUtils.isNotBlank(instrumentInfoEntity.getIdCard())) {
            idCard = instrumentInfoEntity.getIdCard();
            // 舒张压
            Double szyValue = Double.parseDouble(bpUploadModel.getDia());
            // 收缩压
            Double ssyValue = Double.parseDouble(bpUploadModel.getSys());
            // 周期脉搏
            Double heartRate = Double.parseDouble(bpUploadModel.getPul());
            Date testTime = DateUtils.strToDate(bpUploadModel.getTime(), DateUtils.YYYYMMDDHHMMSS);

            testResultService.saveBloodPressure(bpUploadModel.getImei(), idCard, szyValue, ssyValue, heartRate, testTime);

            SysUserEntity sysUserEntity = getOpenIdByIdCard(idCard);
            if (Objects.nonNull(sysUserEntity)) {
                String openId = sysUserEntity.getWxOpenId();
                try {
                    pushBpMpMsg(DateUtils.parseDateToStr( DateUtils.YYYY_MM_DD_HH_MM_SS,testTime), sysUserEntity.getRealName(), bpUploadModel.getSys(), bpUploadModel.getDia(), bpUploadModel.getPul(), openId);
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
            }
        }
        bpUploadModel.setIdCard(idCard);
        smartService.bpUpload(bpUploadModel);
        //数据推送

        Order order = new Order();
        order.setId(new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + "&" + UUID.randomUUID().toString());
        order.setName("血压数据上传");
        order.setMessageId(bpUploadModel.getImei() + "&" +
                new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + "&" + UUID.randomUUID().toString());
        orderService.createOrder(order, FastJsonConvertUtil.convertObjectToJSON(bpUploadModel));
//        producer.sendMessage(JSON.toJSON(bpUploadModel), Constants.SMART_DIRECT, Constants.SMART_BP_ROUTINGKEY, order.getMessageId());


        R r = new R();
        r.put("code", 1);
        r.put("status", "success");
        r.put("msg", "上传数据成功");
        return r;
    }


    /**
     * 脉搏波 - 血压测试结果上传 GET方式
     *
     * @param jsonData
     * @return
     */
    @RequestMapping(value = "/bpUpload/bpg", method = RequestMethod.POST)
    public R bpUploadbpg2Post(@RequestParam(value = "threeJsonData", required = false) final String jsonData) throws Exception {

        BpUploadModel2BPG bpUploadModel2BPG = new Gson().fromJson(jsonData, BpUploadModel2BPG.class);
        log.info(" 脉搏波 - 血压测试结果上传，接受到的参数为:" + JSON.toJSON(bpUploadModel2BPG));
        logger.info(" 脉搏波 - 血压测试结果上传，接受到的参数为:" + JSON.toJSON(bpUploadModel2BPG));
        log.info("POST 接收到血压机上传数据：{}", bpUploadModel2BPG);

        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
        TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
        TimeZone.setDefault(tz);

        BpUploadModel bpUploadModel = new BpUploadModel();
        bpUploadModel.setDia(bpUploadModel2BPG.getLowVoltage());
        bpUploadModel.setImei(bpUploadModel2BPG.getDeviceSim());
        bpUploadModel.setPul(bpUploadModel2BPG.getPulse());
        bpUploadModel.setSys(bpUploadModel2BPG.getHighPressure());
        bpUploadModel.setAno("0");
        bpUploadModel.setTime(bpUploadModel2BPG.getUploadTime());
        bpUploadModel.setUser("3");

        String idCard = "";
        //数据推送
        InstrumentInfoEntity instrumentInfoEntity = instrumentInfoService.getBySn(bpUploadModel.getImei());
        if (Objects.nonNull(instrumentInfoEntity) && org.apache.commons.lang3.StringUtils.isNotBlank(instrumentInfoEntity.getIdCard())) {
            idCard = instrumentInfoEntity.getIdCard();
            // 舒张压
            Double szyValue = Double.parseDouble(bpUploadModel.getDia());
            // 收缩压
            Double ssyValue = Double.parseDouble(bpUploadModel.getSys());
            // 周期脉搏
            Double heartRate = Double.parseDouble(bpUploadModel.getPul());
            Date testTime = DateUtils.strToDate(bpUploadModel.getTime(), DateUtils.YYYYMMDDHHMMSS);

            testResultService.saveBloodPressure(bpUploadModel.getImei(), idCard, szyValue, ssyValue, heartRate, testTime);

            SysUserEntity sysUserEntity = getOpenIdByIdCard(idCard);
            if (Objects.nonNull(sysUserEntity)) {
                String openId = sysUserEntity.getWxOpenId();
                try {
                    pushBpMpMsg(DateUtils.parseDateToStr( DateUtils.YYYY_MM_DD_HH_MM_SS,testTime), sysUserEntity.getRealName(), bpUploadModel.getSys(), bpUploadModel.getDia(), bpUploadModel.getPul(), openId);
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
            }
        }
        bpUploadModel.setIdCard(idCard);
        smartService.bpUpload(bpUploadModel);
        Order order = new Order();
        order.setId(new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + "&" + UUID.randomUUID().toString());
        order.setName("血压数据上传");
        order.setMessageId(bpUploadModel.getImei() + "&" +
                new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + "&" + UUID.randomUUID().toString());
        orderService.createOrder(order, FastJsonConvertUtil.convertObjectToJSON(bpUploadModel));
//        producer.sendMessage(JSON.toJSON(bpUploadModel), Constants.SMART_DIRECT, Constants.SMART_BP_ROUTINGKEY, order.getMessageId());


        /**
         *  数据上传到动康
         *  1、多线程启动(延迟2秒 sleep)
         *  2、用try catch
         *  3、上传
         *  ###############################################################
         *   imei:  设备IME
         *
         *   sql: select idCard,valueunit,TestItemCode,TestItemName,TestTime from testresult where MKMedicalinstrumentId =  '2AM28R00382' ORDER BY id desc LIMIT 100
         *
         *
         * */
        boolean result = ArrayUtils.contains(bpArr, bpUploadModel.getImei());
        if (result == true) {
            smartService.bpExecuteAsync(bpUploadModel);
        }
        R r = new R();
        r.put("code", 1);
        r.put("status", "success");
        r.put("msg", "上传数据成功");
        return r;
    }


    @ApiOperation(value = "微策NB血糖仪", notes = "微策NB血糖仪接口")
    @RequestMapping(value = "/upload/nb", method = RequestMethod.POST)
    // todo
    public String recive(@RequestBody String body, @RequestHeader String signature) throws Exception {
        //第三方对数据进行签名校验(数据体+salt 进行md5加密一次比较值)
        String signatureLocal = MD5Util.MD5Encode(body + SALT);
/*        if (!signature.equals(signatureLocal)) {
            return JsonResult.toString(NetworkCode.CODE_FAIL, "校验数据失败!");
        }*/
        //获取测量数据类型
        Integer sample = JSONObject.parseObject(body).getInteger("sample");
        log.info("微策NB血糖仪，接受到的参数为:" + JSON.toJSON(body));
        logger.info("微策NB血糖仪，接受到的参数为:" + JSON.toJSON(body));
        switch (sample) {
            case 1:
                parseGluObject(body);
                break;
            case 2:
                parseGluObject(body);
                break;
            case 3:
                parseKetObject(body);
                break;
            case 4:
                parseUaObject(body);
                break;
            default:
                return JsonResult.toString(NetworkCode.CODE_FAIL, "不支持的数据类型!");
        }


        /**
         *  数据上传到动康
         * */
        //校验成功，进行后续处理 todo
        return JsonResult.toString(NetworkCode.CODE_SUCCESS, "数据获取成功!");
    }

    //fastjson反序列化

    //血糖
    private void parseGluObject(String body) throws Exception {
        Glucose glucose = JSON.parseObject(body, Glucose.class);
        Msgdata msgdata = new Msgdata();
        msgdata.setDevicesn(glucose.getSn());
        msgdata.setUsercode("10063");//微策NB用10063
        msgdata.setResult(glucose.getValue().toString());
        msgdata.setUnit("0");
        msgdata.setTesttime(glucose.getMeasureTime());
        msgdata.setFoodstatus(glucose.getTimeType().toString());
        msgdata.setOpenid("");

        Order order = new Order();
        order.setId(new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + "&" + UUID.randomUUID().toString());
        order.setName("血糖数据上传");
        order.setMessageId(msgdata.getDevicesn() + "&" +
                new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + "&" + UUID.randomUUID().toString());
        orderService.createOrder(order, FastJsonConvertUtil.convertObjectToJSON(msgdata));
        //数据推动到队列
/*        producer.sendMessage(JSON.toJSON(msgdata),
                Constants.SMART_DIRECT, Constants.SMART_BS_ROUTINGKEY, order.getMessageId());*/

        // todo
        // 根据imei查询身份证号
        String idCard = "";
        InstrumentInfoEntity instrumentInfoEntity = instrumentInfoService.getBySn(glucose.getSn());
        if (Objects.nonNull(instrumentInfoEntity) && org.apache.commons.lang3.StringUtils.isNotBlank(instrumentInfoEntity.getIdCard())) {
            idCard = instrumentInfoEntity.getIdCard();
            TestResult testresult = new TestResult();
            testresult.setTestTime(DateUtils.strToDate(glucose.getMeasureTime(), DateUtils.YYYY_MM_DD_HH_MM_SS));
            testresult.setIdCard(idCard);
            testresult.setMkMedicalInstrumentId(glucose.getSn());
            testresult.setValueUnit("mmol/L");
            testresult.setTestValue(glucose.getValue().toString());


            Date testTime = testresult.getTestTime();
            // 如果testTime 在0点和早上8点之间
            if (testTime.getHours() > 0 && testTime.getHours() < 8) {
                testresult.setTestItemCode("105001");
            } else {
                testresult.setTestItemCode("105002");
            }

            testResultService.saveBloodSugar(testresult);

            SysUserEntity sysUserEntity = getOpenIdByIdCard(idCard);
            if (Objects.nonNull(sysUserEntity)) {
                String openId = sysUserEntity.getWxOpenId();
                if (org.apache.commons.lang3.StringUtils.isNotBlank(openId)) {
                    try {
                        pushBsMpMsg(msgdata.getTesttime(), msgdata.getResult(), openId, testresult.getTestItemCode());
                    } catch (Exception e) {
                        log.error(e.getMessage(), e);
                    }
                }
            }
        }
        msgdata.setIdCard(idCard);
        smartService.bsUpload(msgdata);
        /**
         *  数据上传到动康
         *  1、多线程启动(延迟2秒 sleep)
         *  2、用try catch
         *  3、上传
         *  ###############################################################
         *   imei:  设备IME
         *
         * */
        boolean result = ArrayUtils.contains(bsArr, msgdata.getDevicesn());
        if (result == true) {
            smartService.bsExecuteAsync(msgdata);
        }
    }

    public static void main(String[] args) throws WxErrorException {
        String openId = "oP-XW5hzsI28OuAIyQa1zqEWBCQo";
        WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl();
        config.setAppId("wxd03d26e78f45bfd9"); // 设置微信公众号的appid
        config.setSecret("93753a500c8b281b134f085b81a9ae2b"); // 设置微信公众号的app corpSecret


        WxMpService wxService = new WxMpServiceImpl();// 实际项目中请注意要保持单例，不要在每次请求时构造实例，具体可以参考demo项目
        wxService.setWxMpConfigStorage(config);

        // 发送模板消息接口
        WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                // 接收者openid
                .toUser(openId)
                // 模板id
                .templateId("t_uO4jOw2wj98UG78dxy68sX7ZeOIiQhOzmmkmDp6q4")
                // 模板跳转链接
                .build();
        // 添加模板数据
        templateMessage.addData(new WxMpTemplateData("time3", "您好", "#FF00FF"))
                .addData(new WxMpTemplateData("thing6", "这还是个测试", "#000000"));
        String msgId = null;
        try {
            // 发送模板消息
            msgId = wxService.getTemplateMsgService().sendTemplateMsg(templateMessage);
        } catch (WxErrorException e) {
            e.printStackTrace();
        }
    }

    //血酮
    private void parseKetObject(String body) throws Exception {
        Ketone ketone = JSON.parseObject(body, Ketone.class);
    }

    //尿酸
    private void parseUaObject(String body) throws Exception {
        UricAcid uricAcid = JSON.parseObject(body, UricAcid.class);
    }


    /**
     * 掌护云 握手 预警接口
     *
     * @param nonce
     * @param timestamp
     * @param signature
     * @return
     */
    @GetMapping("/notify_url")
    public String options(@RequestParam(value = "nonce", required = false) String nonce,
                          @RequestParam(value = "timestamp", required = false) String timestamp,
                          @RequestParam(value = "signature", required = false) String signature,
                          @RequestParam(value = "echostr", required = false) String echostr) {

        log.info("接受到掌护云的激活请求，请求参数：echostr:{}", echostr);

        String arr[] = {TOKEN_掌护云, timestamp, nonce};
        Arrays.sort(arr);
        StringBuilder content = new StringBuilder();
        for (String s : arr) {
            content.append(s);
        }

        String afterSignature = MD5Util.MD5Encode(content.toString()).toUpperCase();

        //不做校验,预警处理，直接原样返回
        return echostr;

    }

    /**
     * 掌护云 血压计数据
     *
     * @return
     */
    @PostMapping(value = "/notify_url", consumes = "text/plain;charset=UTF-8")
    public String getZhyBpData(@RequestParam(value = "nonce", required = false) String nonce,
                               @RequestParam(value = "timestamp", required = false) String timestamp,
                               @RequestParam(value = "signature", required = false) String signature,
                               @RequestParam(value = "echostr", required = false) String echostr,
                               @RequestParam(value = "msgType", required = false) String msgType,
                               @RequestBody String aicareParam) throws Exception {
        log.info("接受到掌护云的血压计数据：aicareParam:{}", aicareParam);

        AicareParam aicareParams = JSON.parseObject(aicareParam, AicareParam.class);
        String msgType1 = aicareParams.getMsgType();
        List<Map> content = (List<Map>) aicareParams.getContent();
        if (msgType1.equals("bloodPressureTest")) {
            for (Map co : content) {
                //血压数据保存
                BpUploadModel bpUploadModel = new BpUploadModel();
                bpUploadModel.setDia(co.get("dbp").toString());
                bpUploadModel.setImei(co.get("deviceImei").toString());
                bpUploadModel.setPul(co.get("hr").toString());
                bpUploadModel.setSys(co.get("sbp").toString());
                bpUploadModel.setAno("0");
                bpUploadModel.setTime(co.get("createTime").toString());
                bpUploadModel.setUser("4");
                smartService.bpUpload(bpUploadModel);

                //数据推送
                Order order = new Order();
                order.setId(new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + "&" + UUID.randomUUID().toString());
                order.setName("血压数据上传");
                order.setMessageId(bpUploadModel.getImei() + "&" +
                        new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + "&" + UUID.randomUUID().toString());
                orderService.createOrder(order, FastJsonConvertUtil.convertObjectToJSON(bpUploadModel));
//                producer.sendMessage(JSON.toJSON(bpUploadModel), Constants.SMART_DIRECT, Constants.SMART_BP_ROUTINGKEY, order.getMessageId());
            }
        }

        return "success";
    }

    /**
     * 激活掌护云数据推送
     */
    @GetMapping("/zhy/active")
    public void notifyActive() {
        String method = "/organ/notifyActive";
        String timestamp = DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN);
        String signature = SignatureUtils.getAicareSign(method, ACCESS_KEY, timestamp);
        String format = "json";
        String v = "1.0.0";

        Map<String, String> params = new HashMap<>();
        params.put("method", method);
        params.put("access_id", ACCESS_ID);
        params.put("timestamp", timestamp);
        params.put("signature", signature);
        params.put("format", format);
        params.put("v", v);

        String url = "http://" + "business.aicares.net" + "/api";
        String result = HttpClientUtil.doPost(url, params);
        log.info(result);
        log.info("成功");
    }
}
